package com.gnerv.sylvanas.business.manage.logic;

import com.gnerv.sylvanas.framework.common.model.RestResult;
import com.gnerv.sylvanas.framework.core.BaseUkIdGenerate;
import com.gnerv.sylvanas.business.manage.model.bo.AccountBO;
import com.gnerv.sylvanas.business.manage.model.dto.AccountCreateDTO;
import com.gnerv.sylvanas.business.manage.model.dto.AccountDTO;
import com.gnerv.sylvanas.business.manage.model.dto.AccountDetailsDTO;
import com.gnerv.sylvanas.business.manage.model.dto.AccountRoleDTO;
import com.gnerv.sylvanas.business.manage.model.dto.AccountUpdateDTO;
import com.gnerv.sylvanas.business.manage.operation.AccountOperationService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author Gnerv LiGen
 */
@Slf4j
@Service
@AllArgsConstructor
public class AccountLogicService  {

    private final AccountOperationService accountOperationService;
    private final BaseUkIdGenerate baseUkIdGenerate;

    
    @Transactional(rollbackFor = {Exception.class})
    public RestResult<Void> create(AccountCreateDTO accountCreateDTO) {
        AccountBO accountBO = accountCreateDTO.toAccountBO();
        accountBO.setUkId(baseUkIdGenerate.generate());
        accountOperationService.create(accountBO);
        accountOperationService.bindRole(accountBO.getUkId(), accountCreateDTO.getRoleUkIdList());
        accountOperationService.bindOrg(accountBO.getUkId(), accountCreateDTO.getOrgUkId());
        return RestResult.ok();
    }

    
    @Transactional(rollbackFor = {Exception.class})
    public RestResult<Void> deleteByUkId(String ukId) {
        accountOperationService.deleteByUkId(ukId);
        accountOperationService.unbindRole(ukId);
        return RestResult.ok();
    }

    
    @Transactional(rollbackFor = {Exception.class})
    public RestResult<Void> updateByUkId(AccountUpdateDTO accountUpdateDTO) {
        AccountBO accountBO = accountUpdateDTO.toAccountBO();
        accountOperationService.updateByUkId(accountBO);
        accountOperationService.unbindOrg(accountBO.getUkId());
        accountOperationService.bindOrg(accountBO.getUkId(), accountUpdateDTO.getOrgUkId());
        accountOperationService.unbindRole(accountBO.getUkId());
        accountOperationService.bindRole(accountBO.getUkId(), accountUpdateDTO.getRoleUkIdList());
        return RestResult.ok();
    }

    
    @Transactional(readOnly = true)
    public RestResult<AccountDTO> selectByUkId(String ukId) {
        return RestResult.ok(accountOperationService.selectByUkId(ukId));
    }

    
    public RestResult<AccountDetailsDTO> selectDetailsByUkId(String ukId) {
        return RestResult.ok(accountOperationService.selectDetailsByUkId(ukId));
    }

    
    @Transactional(readOnly = true)
    public RestResult<List<AccountDTO>> selectListByUsername(String username, int page, int size) {
        List<AccountDTO> accountDTOList = accountOperationService.selectListByUsername(username, page, size);
        int count = accountOperationService.selectCountByUsername(username);
        return RestResult.ok(accountDTOList).page(page, size, count);
    }

    
    @Transactional(readOnly = true)
    public RestResult<List<AccountDTO>> selectListByRoleUkId(String roleUkId) {
        return RestResult.ok(accountOperationService.selectListByRoleUkId(roleUkId));
    }

    
    public RestResult<List<AccountDTO>> selectListByOrgUkId(String orgUkId) {
        return RestResult.ok(accountOperationService.selectListByOrgUkId(orgUkId));
    }

    
    public RestResult<Void> bindRole(AccountRoleDTO accountRoleDTO) {
        accountOperationService.unbindRole(accountRoleDTO.getAccountUkId());
        accountOperationService.bindRole(accountRoleDTO.getAccountUkId(), accountRoleDTO.getRoleUkIdList());
        return RestResult.ok();
    }

    
    public RestResult<Void> unbindRole(String accountUkId) {
        accountOperationService.unbindRole(accountUkId);
        return RestResult.ok();
    }

    
    public RestResult<List<AccountDetailsDTO>> selectListDetailsByOrgUkId(String orgUkId) {
        return RestResult.ok(accountOperationService.selectListDetailsByOrgUkId(orgUkId));
    }

    
    public RestResult<List<AccountDetailsDTO>> selectListDetailsByUsername(String username, int page, int size) {
        List<AccountDetailsDTO> accountDetailsDTOList = accountOperationService.selectListDetailsByUsername(username, page, size);
        int count = accountOperationService.selectCountByUsername(username);
        return RestResult.ok(accountDetailsDTOList).page(page, size, count);
    }

}
